﻿using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;

namespace ServiceCore.Utility.Extension
{
    public static class UtiyityText
    {
        /// <summary>
        /// 获取字符串中的数字
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string GetTxtReplaceNumeric(this string input) 
        {
            input = input.Replace("  ", " ");
            input = input.Replace(" ", ",");
            input = input.Replace(" ", ",");
            input = input.Replace(".", ",");
            input = input.Replace("。", ",");
            input = input.Replace("/", ",");
            input = input.Replace("-", ",");
            input = input.Replace("+", ",");
            input = input.Replace("和", ",");
            input = input.Replace(" ", ",");
            return input;
        }

        /// <summary>
        /// 是否包含数字
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsHaveNumeric(this string input)
        {
            if (string.IsNullOrEmpty(input)) return false;

            for (int i = 0; i < input.Length; i++)
            {
                char c = input[i];
                if (c >= '0' && c <= '9') return true;
            }
            return false;
        }
        /// <summary>
        /// 字符串是否全部为数字
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsAllNumeric(this string input)
        {
            if (string.IsNullOrWhiteSpace(input))
                return false;

            return input.All(c => char.IsDigit(c) || char.IsWhiteSpace(c)) &&
                   input.Any(char.IsDigit);
        }
        /// <summary>
        /// 获取字符出现次数
        /// </summary>
        /// <param name="input"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        public static int GetCharCount(this string input, char target)
        {
            int count = 0;
            foreach (char c in input)
            {
                if (c == target)
                    count++;
            }
            return count;
        }
        /// <summary>
        /// 获取文字中的数字
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static long? GetTxtNumeric(this string input)
        {
            List<long> result = GetTxtNumerics(input);
            if (result.Any() == false)
                return null;

            return result[0];
        }
        /// <summary>
        /// 批量获取文字中的数字
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static List<long> GetTxtNumerics(this string input)
        {
            List<long> result = new List<long>();

            MatchCollection matches = Regex.Matches(input, @"\d+");
            if (matches != null && matches.Any())
            {
                long value = 0;
                foreach (Match match in matches)
                {
                    long.TryParse(match.Value, out value);
                    if (value > 0)
                        result.Add(value);
                }
            }

            return result;
        }

        /// <summary>
        /// 替换字符串最最后一个逗号
        /// </summary>
        /// <param name="input"></param>
        /// <param name="replacement"></param>
        /// <returns></returns>
        public static string ReplaceLastComma(this string input, string replacement)
        {
            int lastCommaIndex = input.LastIndexOf(',');
            if (lastCommaIndex == -1)
                return input;

            return input.Remove(lastCommaIndex, 1).Insert(lastCommaIndex, replacement);
        }

        /// <summary>
        /// 字符串中第一个数字值前加一个字符（例如："猴100总计145"FirstNumberBeforeAddTxt("打") = "猴打100总计145"）
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string FirstNumberBeforeAddTxt(this string input, string appendTxt)
        {
            if (string.IsNullOrEmpty(appendTxt))
                return input;

            // 使用ReadOnlySpan<char>避免内存分配
            ReadOnlySpan<char> span = input.AsSpan();

            // 手动遍历查找第一个数字
            for (int i = 0; i < span.Length; i++)
            {
                if (char.IsDigit(span[i]))
                {
                    // 找到数字起始位置后，继续查找数字结束位置
                    int start = i;
                    while (i < span.Length && char.IsDigit(span[i]))
                    {
                        i++;
                    }

                    // 使用StringBuilder避免多次字符串拼接
                    var builder = new System.Text.StringBuilder(input.Length + 1);
                    builder.Append(span.Slice(0, start));
                    builder.Append(appendTxt);
                    builder.Append(span.Slice(start, i - start));
                    builder.Append(span.Slice(i));

                    return builder.ToString();
                }
            }

            return input; // 没有找到数字则返回原字符串
        }
        /// <summary>
        /// 字符串中第一个数字值后加一个字符
        /// </summary>
        /// <param name="input"></param>
        /// <param name="appendTxt"></param>
        /// <returns></returns>
        public static string FirstNumberValueEndAddTxt(this string input, string appendTxt)
        {
            ReadOnlySpan<char> span = input.AsSpan();
            int start = -1, end = -1;

            // 使用Span手动查找数字范围
            for (int i = 0; i < span.Length; i++)
            {
                if (char.IsDigit(span[i]))
                {
                    if (start == -1) start = i;
                    end = i;
                }
                else if (start != -1)
                {
                    break; // 找到第一个数字序列后立即停止
                }
            }

            if (start != -1)
            {
                // 使用String.Create避免中间字符串分配
                return string.Create(input.Length + 1, (input, start, end), (chars, state) =>
                {
                    state.input.AsSpan().CopyTo(chars);
                    chars[state.end + 1] = '打';
                    state.input.AsSpan(state.end + 1).CopyTo(chars[(state.end + 2)..]);
                });
            }

            return input;
        }

        /// <summary>
        /// 字符串中最后一个数字值后加一个字符
        /// </summary>
        /// <param name="input">输入字符串</param>
        /// <param name="appendTxt">要添加的文字</param>
        /// <returns>处理后的字符串</returns>
        public static string LastNumberValueEndAddTxt(this string input, string appendTxt)
        {
            if (string.IsNullOrEmpty(input) || string.IsNullOrEmpty(appendTxt))
                return input;

            ReadOnlySpan<char> span = input.AsSpan();
            int lastNumberEnd = -1;

            // 从后向前查找最后一个数字序列的结束位置
            for (int i = span.Length - 1; i >= 0; i--)
            {
                if (char.IsDigit(span[i]))
                {
                    lastNumberEnd = i;
                    // 继续向前查找数字序列的开始
                    while (i > 0 && char.IsDigit(span[i - 1]))
                    {
                        i--;
                    }
                    break; // 找到最后一个数字序列后停止
                }
            }

            if (lastNumberEnd != -1)
            {
                // 在最后一个数字后面插入文本
                return string.Create(input.Length + appendTxt.Length,
                    (input, lastNumberEnd, appendTxt), (chars, state) =>
                    {
                        // 复制第一个部分（到最后一个数字）
                        state.input.AsSpan(0, state.lastNumberEnd + 1).CopyTo(chars);

                        // 复制要添加的文本
                        state.appendTxt.AsSpan().CopyTo(chars.Slice(state.lastNumberEnd + 1, state.appendTxt.Length));

                        // 复制剩余部分
                        if (state.lastNumberEnd + 1 < state.input.Length)
                        {
                            state.input.AsSpan(state.lastNumberEnd + 1).CopyTo(
                        chars.Slice(state.lastNumberEnd + 1 + state.appendTxt.Length));
                        }
                    });
            }

            return input;
        }

        /// <summary>
        /// 使用String.IndexOf获取第一个匹配值
        /// </summary>
        public static string FindFirstMatchIndexOf(this string input, IReadOnlyList<string> targets)
        {
            if (string.IsNullOrEmpty(input) || targets == null || targets.Count == 0)
                return null;

            foreach (string target in targets)
            {
                if (string.IsNullOrEmpty(target))
                    continue;

                if (input.IndexOf(target, StringComparison.Ordinal) >= 0)
                {
                    return target;
                }
            }

            return null;
        }
    }
}

